/******************************************************************************
 * * desktop_dial.c - implementation of dial functions
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "desktop_global.h"


/**
 * Callback function for handling key pressed on Dial_Opt interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Framework_Dial_Opt_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    UINT8 Ret = 1; // not call default key function for List

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_SOFTRIGHT:
            Nav_Back(ACT_ID_ANY);
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        case KEY_OK:
        case KEY_UP:
        case KEY_DOWN:
        case KEY_LEFT:
        case KEY_RIGHT:
            Framework_Press_Direction_Key_On_List(Key_Val);
            Ret = 0; // call default key function for List
            break;

        default:
            break;
        } /* switch */
    }

    return(Ret);
}


/**
 * Action if pressing call button on Dial_Opt interface
 * param (in) Btn: lv_obj_t *
 * param (in) Event: lv_event_t
 * return  VOID
 */
VOID Framework_Dial_Opt_Btn_Call_Cb(lv_obj_t *Btn, lv_event_t Event)
{
    INT8  *Number;
    UINT8 Len;

    if (LV_EVENT_CLICKED != Event)
    {
        return;
    }

    Len    = strlen(g_FrameworkMng.PhoneNumber) + 1;
    Number = (INT8 *)Hal_Mem_Alloc(Len);
    memcpy(Number, g_FrameworkMng.PhoneNumber, Len);
    Nav_Back(ACT_ID_ANY);
    Nav_Back(ACT_ID_ANY);
    Call_Framework_Voice_Call_Req(Number);
}


/**
 * Action if pressing save button on Dial_Opt interface
 * param (in) Btn: lv_obj_t *
 * param (in) Event: lv_event_t
 * return  VOID
 */
VOID Framework_Dial_Opt_Btn_Save_Cb(lv_obj_t *Btn, lv_event_t Event)
{
    INT8  *Number;
    UINT8 Len;

    if (LV_EVENT_CLICKED != Event)
    {
        return;
    }

    Len    = strlen(g_FrameworkMng.PhoneNumber) + 1;
    Number = (INT8 *)Hal_Mem_Alloc(Len);
    memcpy(Number, g_FrameworkMng.PhoneNumber, Len);
    Contacts_Save_Contact_Req(ACT_ID_DIAL_MAIN, Number);
}


/**
 * Action if pressing send message button on Dial_Opt interface
 * param (in) Btn: lv_obj_t *
 * param (in) Event: lv_event_t
 * return  VOID
 */
VOID Framework_Dial_Opt_Btn_Send_Sms_Cb(lv_obj_t *Btn, lv_event_t Event)
{
    INT8  *Number;
    UINT8 Len;

    if (LV_EVENT_CLICKED != Event)
    {
        return;
    }

    Len    = strlen(g_FrameworkMng.PhoneNumber) + 1;
    Number = (INT8 *)Hal_Mem_Alloc(Len);
    memcpy(Number, g_FrameworkMng.PhoneNumber, Len);
    Nav_Back(ACT_ID_ANY);
    Nav_Back(ACT_ID_ANY);
    Framework_Sms_Send_Message_Req(Number);
}


/**
 * Action if pressing add to number screening list button on Dial_Opt interface
 * param (in) Btn: lv_obj_t *
 * param (in) Event: lv_event_t
 * return  VOID
 */
VOID Framework_Dial_Opt_Btn_Add_To_Sl_Cb(lv_obj_t *Btn, lv_event_t Event)
{
    INT8  *Number;
    UINT8 Len;

    if (LV_EVENT_CLICKED != Event)
    {
        return;
    }

    Len    = strlen(g_FrameworkMng.PhoneNumber) + 1;
    Number = (INT8 *)Hal_Mem_Alloc(Len);
    memcpy(Number, g_FrameworkMng.PhoneNumber, Len);
    Contacts_Add_Num_To_Scrn_List_Req(ACT_ID_DIAL_MAIN, Number);
}


/**
 * Action if pressing delete from number screening list button on Dial_Opt interface
 * param (in) Btn: lv_obj_t *
 * param (in) Event: lv_event_t
 * return  VOID
 */
VOID Framework_Dial_Opt_Btn_Del_From_Sl_Cb(lv_obj_t *Btn, lv_event_t Event)
{
    INT8  *Number;
    UINT8 Len;

    if (LV_EVENT_CLICKED != Event)
    {
        return;
    }

    printf("%s: number %s", __FUNCTION__, g_FrameworkMng.PhoneNumber);
    Len    = strlen(g_FrameworkMng.PhoneNumber) + 1;
    Number = (INT8 *)Hal_Mem_Alloc(Len);
    memcpy(Number, g_FrameworkMng.PhoneNumber, Len);
    Contacts_Del_Num_From_Scrn_List_Req(ACT_ID_DIAL_MAIN, Number);
}


/**
 * Callback function for additional actions after Creating Dial_Opt interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Dial_Opt_OnCreate(VOID *Ctrl)
{
    lv_label_set_text(((UI_Normal_List_Only_Desc_t *)Ctrl)->TitleBar.Label,
                      g_FrameworkMng.PhoneNumber);
}


/**
 * Callback function for restoring state on Dial_Opt interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Dial_Opt_OnRestoreState(VOID *Ctrl)
{
    lv_label_set_text(((UI_Normal_List_Only_Desc_t *)Ctrl)->TitleBar.Label,
                      g_FrameworkMng.PhoneNumber);
}


/**
 * Callback function for destroying Dial_Opt interface which will be popped from stack
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Dial_Opt_OnDestroy(VOID *Ctrl)
{
    Hal_Mem_Free(((UI_Normal_List_Only_Desc_t *)Ctrl)->List.ButtonList);
    Hal_Mem_Free(Ctrl);
}


/**
 * Create Dial_Opt interface
 * param (in) VOID
 * return  VOID
 */
VOID Framework_Create_Dial_Opt()
{
    UI_Normal_List_Only_Desc_t *NormalLstOnlyDesc;
    Nav_Func_List_t            FuncList;
    UINT32                     Len;

    NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(NormalLstOnlyDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    NormalLstOnlyDesc->TitleBar.TxtId      = LV_LANG_TXT_ID_NONE;
    NormalLstOnlyDesc->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    NormalLstOnlyDesc->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    NormalLstOnlyDesc->List.ListButtonCnt = 4;
    Len                                   = sizeof(UI_Button_Desc_t) *
                                            NormalLstOnlyDesc->List.ListButtonCnt;
    NormalLstOnlyDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Len);
    Hal_Mem_Set(NormalLstOnlyDesc->List.ButtonList, 0, Len);

    NormalLstOnlyDesc->List.ButtonList[0].Valid       = TRUE;
    NormalLstOnlyDesc->List.ButtonList[0].ButtonIndex = 0;
    NormalLstOnlyDesc->List.ButtonList[0].TxtId       = PHONE_TEXT_ID_CALL;
    NormalLstOnlyDesc->List.ButtonList[0].ReleaseFun  = Framework_Dial_Opt_Btn_Call_Cb;

    NormalLstOnlyDesc->List.ButtonList[1].Valid       = TRUE;
    NormalLstOnlyDesc->List.ButtonList[1].ButtonIndex = 1;
    NormalLstOnlyDesc->List.ButtonList[1].TxtId       = PHONE_TEXT_ID_SAVE;
    NormalLstOnlyDesc->List.ButtonList[1].ReleaseFun  = Framework_Dial_Opt_Btn_Save_Cb;

    NormalLstOnlyDesc->List.ButtonList[2].Valid       = TRUE;
    NormalLstOnlyDesc->List.ButtonList[2].ButtonIndex = 2;
    NormalLstOnlyDesc->List.ButtonList[2].TxtId       = PHONE_TEXT_ID_SEND_SMS;
    NormalLstOnlyDesc->List.ButtonList[2].ReleaseFun  = Framework_Dial_Opt_Btn_Send_Sms_Cb;

    NormalLstOnlyDesc->List.ButtonList[3].Valid       = TRUE;
    NormalLstOnlyDesc->List.ButtonList[3].ButtonIndex = 3;
    if (FALSE == Contacts_Is_In_Num_Scrn_List(g_FrameworkMng.PhoneNumber))
    {   /* phone number is not in screening list */
        NormalLstOnlyDesc->List.ButtonList[3].TxtId      = PHONE_TEXT_ID_ADD_TO_SL;
        NormalLstOnlyDesc->List.ButtonList[3].ReleaseFun = Framework_Dial_Opt_Btn_Add_To_Sl_Cb;
    }
    else
    {   /* phone number is in screening list */
        NormalLstOnlyDesc->List.ButtonList[3].TxtId      = PHONE_TEXT_ID_DEL_FROM_SCRLIST;
        NormalLstOnlyDesc->List.ButtonList[3].ReleaseFun = Framework_Dial_Opt_Btn_Del_From_Sl_Cb;
    }

    NormalLstOnlyDesc->BtnBar.ButtonL.Valid = FALSE;
    NormalLstOnlyDesc->BtnBar.ButtonM.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;
    NormalLstOnlyDesc->BtnBar.ButtonR.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    NormalLstOnlyDesc->KeyFunc = Framework_Dial_Opt_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_List_Only_Create;
    FuncList.OnCreate       = Framework_Dial_Opt_OnCreate;
    FuncList.OnRestoreState = Framework_Dial_Opt_OnRestoreState;
    FuncList.OnSaveState    = Framework_Interface_OnSaveState;
    FuncList.OnDestroy      = Framework_Dial_Opt_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_DIAL_OPT, &FuncList, NormalLstOnlyDesc);
} /* Framework_Create_Dial_Opt */


/**
 * Callback function for handling key pressed on Dial_Main interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Framework_Dial_Main_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    INT8       Char = 0;
    const INT8 *Text;
    INT8       *Output;
    UINT8      Len;

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_0:
            Char = '0';
            break;

        case KEY_1:
            Char = '1';
            break;

        case KEY_2:
            Char = '2';
            break;

        case KEY_3:
            Char = '3';
            break;

        case KEY_4:
            Char = '4';
            break;

        case KEY_5:
            Char = '5';
            break;

        case KEY_6:
            Char = '6';
            break;

        case KEY_7:
            Char = '7';
            break;

        case KEY_8:
            Char = '8';
            break;

        case KEY_9:
            Char = '9';
            break;

        case KEY_ASTERISK:
            Char = '*';
            break;

        case KEY_HASH:
            Char = '#';
            break;

        case KEY_SOFTLEFT:
            Text                                     = lv_textarea_get_text(Obj);
            Len                                      = strlen(Text) + 1;
            if (g_FrameworkMng.PhoneNumber)
            {
                printf("%s: prev number %s\n",
                       __FUNCTION__, g_FrameworkMng.PhoneNumber);
                Hal_Mem_Free(g_FrameworkMng.PhoneNumber);
            }
            g_FrameworkMng.PhoneNumber = (INT8 *)Hal_Mem_Alloc(Len);
            memcpy(g_FrameworkMng.PhoneNumber, Text, Len);
            printf("%s: number %s\n", __FUNCTION__, g_FrameworkMng.PhoneNumber);
            Framework_Create_Dial_Opt();
            break;

        case KEY_SOFTRIGHT: // clear
            lv_textarea_del_char(Obj);
            if (0 == strcmp("", lv_textarea_get_text(Obj)))
            {
                Nav_Home(ACT_ID_ANY);
            }
            break;

        case KEY_DIAL:
            Text   = lv_textarea_get_text(Obj);
            Len    = strlen(Text) + 1;
            Output = (INT8 *)Hal_Mem_Alloc(Len);
            memcpy(Output, Text, Len);
            Nav_Back(ACT_ID_ANY);
            Call_Framework_Voice_Call_Req(Output);
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        case KEY_UP:
            lv_textarea_cursor_up(Obj);
            break;

        case KEY_DOWN:
            lv_textarea_cursor_down(Obj);
            break;

        case KEY_LEFT:
            lv_textarea_cursor_left(Obj);
            break;

        case KEY_RIGHT:
            lv_textarea_cursor_right(Obj);
            break;

        case KEY_OK: // back
            Nav_Home(ACT_ID_ANY);
            break;

        default:
            break;
        } /* switch */

        if (0 != Char)
        {
            lv_textarea_add_char(Obj, Char);
        }
    }

    return(1);
} /* Framework_Dial_Main_Key_Cb */


/**
 * Callback function for additional actions after Creating Dial_Main interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Dial_Main_OnCreate(VOID *Ctrl)
{
    UI_DialPad_Desc_t *Interface = (UI_DialPad_Desc_t *)Ctrl;

    Framework_Output_Operator_On_Desktop(MMI_MODEM_SIM_1,
        Interface->Oper_Label[MMI_MODEM_SIM_1].Label);
    Framework_Output_Operator_On_Desktop(MMI_MODEM_SIM_2,
        Interface->Oper_Label[MMI_MODEM_SIM_2].Label);

    lv_textarea_set_max_length(Interface->PadTa.TextArea, NV_CONTACTS_MAX_NUMBER_LEN - 1);

    if (NULL != Interface->PadTa.TaTxt)
    {
        Hal_Mem_Free(Interface->PadTa.TaTxt);
        Interface->PadTa.TaTxt = NULL;
    }
}


/**
 * Callback function for restoring state on Dial_Main interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Dial_Main_OnRestoreState(VOID *Ctrl)
{
    UI_DialPad_Desc_t *Interface = (UI_DialPad_Desc_t *)Ctrl;

    Framework_Output_Operator_On_Desktop(MMI_MODEM_SIM_1,
        Interface->Oper_Label[MMI_MODEM_SIM_1].Label);
    Framework_Output_Operator_On_Desktop(MMI_MODEM_SIM_2,
        Interface->Oper_Label[MMI_MODEM_SIM_2].Label);

    lv_textarea_set_max_length(Interface->PadTa.TextArea, NV_CONTACTS_MAX_NUMBER_LEN - 1);
    printf("%s: ta txt %s\n", __FUNCTION__, lv_textarea_get_text(Interface->PadTa.TextArea));
    if (NULL != g_FrameworkMng.PhoneNumber)
    {
        Hal_Mem_Free(g_FrameworkMng.PhoneNumber);
        g_FrameworkMng.PhoneNumber = NULL;
    }
}


/**
 * Callback function for destroying Dial_Main interface which will be popped from stack
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Dial_Main_OnDestroy(VOID *Ctrl)
{
    if (NULL != g_FrameworkMng.PhoneNumber)
    {
        Hal_Mem_Free(g_FrameworkMng.PhoneNumber);
        g_FrameworkMng.PhoneNumber = NULL;
    }

    Hal_Mem_Free(Ctrl);
}


/**
 * Callback function for saving state on Dial_Main interface before forward to another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Dial_Main_OnSaveState(VOID *Ctrl)
{
    UI_Text_Area_Desc_t *PadTa = &(((UI_DialPad_Desc_t *)Ctrl)->PadTa);

    PadTa->TaTxt = g_FrameworkMng.PhoneNumber;
    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_2,
        "Framework_Dial_Main_OnSaveState, TaTxt %s\n", PadTa->TaTxt);
}


/**
 * Create Dial_Main interface
 * param (in) VOID
 * return  VOID
 */
VOID Framework_Create_Dial_Main(INT8 *Number)
{
    UI_DialPad_Desc_t *Interface;
    Nav_Func_List_t   FuncList;

    if (NULL == Number)
    {
        /* error */
        return;
    }

    Interface = (UI_DialPad_Desc_t *)Hal_Mem_Alloc(sizeof(UI_DialPad_Desc_t));
    Hal_Mem_Set(Interface, 0, sizeof(UI_DialPad_Desc_t));

    Interface->Oper_Label[0].TxtId      = LV_LANG_TXT_ID_NONE;
    Interface->Oper_Label[0].TxtAlign   = LV_LABEL_ALIGN_LEFT;
    Interface->Oper_Label[0].LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    if (FRAMEWORK_SIM_STATUS_ABSENT == g_FrameworkMng.SimStatus[MMI_MODEM_SIM_1])
    {
        Interface->Oper_Label[0].ImgSrc = SYMBOL_NO_SIM1;
    }
    else
    {
        Interface->Oper_Label[0].ImgSrc = SYMBOL_SIM1;
    }
    Interface->Oper_Label[1].TxtId      = LV_LANG_TXT_ID_NONE;
    Interface->Oper_Label[1].TxtAlign   = LV_LABEL_ALIGN_LEFT;
    Interface->Oper_Label[1].LabelAlign = LV_ALIGN_OUT_BOTTOM_LEFT;
    if (FRAMEWORK_SIM_STATUS_ABSENT == g_FrameworkMng.SimStatus[MMI_MODEM_SIM_2])
    {
        Interface->Oper_Label[1].ImgSrc = SYMBOL_NO_SIM2;
    }
    else
    {
        Interface->Oper_Label[1].ImgSrc = SYMBOL_SIM2;
    }

    Interface->PadTa.TaTxt        = Number;
    Interface->PadTa.TaCursorHide = FALSE;
    Interface->PadTa.TaAlign      = LV_ALIGN_OUT_BOTTOM_LEFT;

    Interface->ButtonBar.ButtonL.Valid = TRUE;
    Interface->ButtonBar.ButtonL.TxtId = PHONE_TEXT_ID_OPT;
    Interface->ButtonBar.ButtonM.Valid = TRUE;
    Interface->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_BACK;
    Interface->ButtonBar.ButtonR.Valid = TRUE;
    Interface->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_CLEAR;

    Interface->KeyFunc = Framework_Dial_Main_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_DialPad_Create;
    FuncList.OnCreate       = Framework_Dial_Main_OnCreate;
    FuncList.OnRestoreState = Framework_Dial_Main_OnRestoreState;
    FuncList.OnSaveState    = Framework_Dial_Main_OnSaveState;
    FuncList.OnDestroy      = Framework_Dial_Main_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_DIAL_MAIN, &FuncList, Interface);
} /* Framework_Create_Dial_Main */


/**
 * Dial from SMS APP
 * param (in) Number: INT8 *
 * return  VOID
 */
VOID Framework_Sms_Dial_Ind(INT8 *Number)
{
    Framework_Create_Dial_Main(Number);
}
